#include <sys/types.h>
#include <sys/stat.h>
#include <poll.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/epoll.h>

void poll_test(int fd)
{
    struct pollfd fds;
    fds.fd = fd;
    fds.events = POLLIN | POLLOUT;

    while (1)
    {
        int res = poll(&fds, 1, 5000);

        if (res < 0)
        {
            perror("poll.");
        }
        else if (res == 0)
        {
            printf("no events.\n");
        }
        else
        {
            for (int i = 0; i < res; i++)
            {
                if (0 != fds.revents)
                {
                    printf("fds revents = %d\n", fds.revents);
                    if (fds.revents & POLLIN)
                    {
                        printf("read event.\n");
                    }
                    if (fds.revents & POLLOUT)
                    {
                        printf("write events.\n");
                    }
                }
            }
        }
    }
}

void epoll_test(int fd)
{
    struct epoll_event ev_globalfifo;
    int err;

    int epfd = epoll_create(1);
    if (epfd < 0)
    {
        perror("epoll_create(1)");
        return;
    }

    bzero(&ev_globalfifo, sizeof(struct epoll_event));
    ev_globalfifo.data.fd = fd;
    ev_globalfifo.events = EPOLLIN | EPOLLOUT | EPOLLET;
    err = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev_globalfifo);
    if (err < 0)
    {
        perror("epoll_ctl()");
        return;
    }

    while (1)
    {
        err = epoll_wait(epfd, &ev_globalfifo, 1, 5000);
        if (err < 0)
        {
            perror("epoll_wait()");
        }
        else if (err == 0)
        {
            printf("no event\n");
        }
        else
        {
            printf("err = %d, events = %d\n", err, ev_globalfifo.events);
            if (ev_globalfifo.events & EPOLLIN)
            {
                printf("read event happen.\n");
            }
            if (ev_globalfifo.events & EPOLLOUT)
            {
                printf("write event happen.\n");
            }
        }
    }

    err = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &ev_globalfifo);
    if (err < 0)
    {
        perror("epoll_ctl()");
    }
}

int main(void)
{
    int fd = open("/dev/simple_epoll", O_RDONLY);

    if (-1 != fd)
    {
        epoll_test(fd);

        close(fd);
    }
    else
    {
        perror("open");
        return -1;
    }
}